"""
Configuration module for sangreal-calendar.

This module centralizes all configuration constants and settings
to improve maintainability and reduce magic numbers throughout the codebase.
"""

from typing import Dict, Any
import os

# Date range constants
DEFAULT_BEGIN_DATE: str = '19900101'
DEFAULT_END_DATE: str = '20990101'
MAX_STEP_FORWARD: int = 600  # Maximum forward step for trade date navigation

# Environment variable names
ENV_COUNTRY: str = 'CN'  # Default country for market operations

# Frequency calculation constants
WEEKLY_DAYS: Dict[int, int] = {
    1: 0,   # Monday
    2: 1,   # Tuesday
    3: 2,   # Wednesday
    4: 3,   # Thursday
    5: 4,   # Friday
    6: -1,  # Saturday (invalid)
    7: -2,  # Sunday (invalid)
}

# Frequency search steps
DAILY_SEARCH_STEPS: int = 600
WEEKLY_OFFSET: int = 20
MONTHLY_OFFSET: int = 40
QUARTERLY_OFFSET: int = 120
YEARLY_OFFSET: int = 300

# Futures configuration constants
FUTURES_START_DATE: str = '20150501'
TREASURY_START_DATE: str = '20151231'
CONTRACT_SWITCH_DAYS: int = 4
YEARS_FORWARD: int = 2

# Format constants
DEFAULT_DATE_FORMAT: str = '%Y%m%d'
FUTURE_DATE_FORMAT: str = '%Y%m%d'

# Futures configuration
FUTURES_DELIVERY_CODES: Dict[str, str] = {
    'TF': 'TF',   # Treasury futures
    'T': 'T',     # Treasury futures
    'TS': 'TS',   # Treasury futures
}

# Calendar cache configuration
CACHE_SIZE: int = 128  # Default cache size for LRU cache

# Error messages
ERROR_MESSAGES: Dict[str, str] = {
    'empty_dates': 'Trade dates series is empty',
    'date_not_found': 'Date not found in calendar',
    'invalid_date_range': 'Invalid date range: begin date must be before end date',
    'step_limit_exceeded': f'Step limit exceeded (max: {MAX_STEP_FORWARD})',
    'invalid_frequency': 'Invalid frequency specified',
    'calendar_not_initialized': 'Calendar not initialized with trade dates',
}

# Validation patterns
DATE_PATTERN: str = r'^\d{8}$'  # YYYYMMDD format validation


class CalendarConfig:
    """
    Centralized configuration class for calendar operations.

    This class provides a single point of configuration management
    and allows for easy customization of calendar behavior.
    """

    def __init__(self,
                 begin_date: str = DEFAULT_BEGIN_DATE,
                 end_date: str = DEFAULT_END_DATE,
                 max_step: int = MAX_STEP_FORWARD,
                 cache_size: int = CACHE_SIZE,
                 country: str = ENV_COUNTRY):
        """
        Initialize calendar configuration.

        Args:
            begin_date: Default begin date for operations
            end_date: Default end date for operations
            max_step: Maximum forward step for navigation
            cache_size: Cache size for LRU caching
            country: Country code for market operations
        """
        self.begin_date = begin_date
        self.end_date = end_date
        self.max_step = max_step
        self.cache_size = cache_size
        self.country = country

    @property
    def default_country(self) -> str:
        """Get the default country code."""
        return self.country

    @default_country.setter
    def default_country(self, country: str) -> None:
        """
        Set the default country code.

        Args:
            country: Country code to set
        """
        self.country = country
        os.environ('COUNTRY', country)

    def validate_date_range(self, begin_date: str, end_date: str) -> bool:
        """
        Validate that a date range is within acceptable bounds.

        Args:
            begin_date: Begin date in YYYYMMDD format
            end_date: End date in YYYYMMDD format

        Returns:
            True if date range is valid, False otherwise
        """
        try:
            begin_int = int(begin_date)
            end_int = int(end_date)
            min_date = int(self.begin_date)
            max_date = int(self.end_date)

            return (min_date <= begin_int <= max_date and
                   min_date <= end_int <= max_date and
                   begin_int <= end_int)
        except ValueError:
            return False

    def get_error_message(self, error_key: str) -> str:
        """
        Get error message by key.

        Args:
            error_key: Key for the error message

        Returns:
            Error message string
        """
        return ERROR_MESSAGES.get(error_key, 'Unknown error')


# Global configuration instance
config = CalendarConfig()